#include <windows.h>
#include <ceddk.h>
#include "BusDrvIf.h"

#include "SianoSPI.h"
#include "smsspiphy.h"

/************************************************************************
*                                                                      *
* FILE NAME:   SianoSPI.cpp                                           *
*                                                                      *
* DESCRIPTION:                                                           *
*                                                                       *
*                                                                      *
* Copyright (C) 2006 Consonance Ltd.                                   *
* All rights reserved                                                  *
*                                                                      *
************************************************************************/

DBGPARAM dpCurSettings = {
    TEXT("BUILTINTEST"), {
    TEXT("Errors"),    TEXT("Warnings"),  TEXT("Init"),        TEXT("Trace"),
    TEXT("SPI_INIT"),  TEXT("SPI_READ"),  TEXT("SPI_WRITE"),   TEXT("SPI_IOCTL"),
    TEXT("SPI_DEINIT"), TEXT("ZONE_FUNCTION"), TEXT("Undefined"), TEXT("Undefined")
    },
     ZONE_ERROR_SET | ZONE_WARNING_SET | ZONE_INIT_SET | ZONE_INFO_SET //| ZONE_DETAILED_SET
};


static CHAR preamble_pattern[] = { 0xa5, 0x5a, 0xe7, 0x7e };

#define RX_BUF_SIZE                        (0x1200)
#define TX_BUF_SIZE                        (0x200)

//#define MAX_REG_PATH_SIZE               (100)
#define MAX_REG_KEY_SIZE                (100)

#define WAIT_FOR_DRIVER_LOADING_TIME    (5000)//waiting to be able to read from reg
#ifdef USE_CONSO_DEFAULT 
//if we are on test mode use the SPI path if it is release use BuiltIn...
#define REG_PATH                        L"Drivers\\SPI\\SianoSPI"
#else
#define REG_PATH                        L"Drivers\\BuiltIn\\SianoSPI"
#endif

#define MAX_MNPRT_NAME                  (64)
//RAN: for debug purpose
extern DWORD gt_Freq;//frequency of the Performance Counter declared in SpiHw.cpp.
DWORD gt_ClntST;
DWORD gt_ClntET;
LARGE_INTEGER Li_Clnt;
DWORD g_RecievedBytes;


static void MsgFound(void* context, void* buf, int offset, int len)
{    
    PSPIDEVICEEXTENSION pSpiDevExt = context;
    DBGMSG(ZONE_INFO, (TEXT("SmsSpi: MsgFound().\r\n")));
    if (pSpiDevExt->pBD_ReadCBFunc)
    {
        DBGMSG(ZONE_INFO, (TEXT("SmsSpi: Calling back with message at offset %d: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, \r\n"),
                                                                                                offset, 
                                                                                    (char*)((char*)(((rx_buffer_st*)buf)->ptr) + offset)[0],
                                                                                    (char*)((char*)(((rx_buffer_st*)buf)->ptr) + offset)[1],
                                                                                    (char*)((char*)(((rx_buffer_st*)buf)->ptr) + offset)[2],
                                                                                    (char*)((char*)(((rx_buffer_st*)buf)->ptr) + offset)[3],
                                                                                    (char*)((char*)(((rx_buffer_st*)buf)->ptr) + offset)[4],
                                                                                    (char*)((char*)(((rx_buffer_st*)buf)->ptr) + offset)[5],
                                                                                    (char*)((char*)(((rx_buffer_st*)buf)->ptr) + offset)[6],
                                                                                    (char*)((char*)(((rx_buffer_st*)buf)->ptr) + offset)[7]));
        pSpiDevExt->pBD_ReadCBFunc(pSpiDevExt->hBDContext, (char*)(((rx_buffer_st*)buf)->ptr) + offset, (DWORD)len);
#ifdef MEASURE_PERFORMANCE
        g_RecievedBytes += len;
#endif
    }
    DBGMSG(ZONE_INFO, (TEXT("SmsSpi: MsgFound end.\r\n")));
    
}

#ifdef MEASURE_PERFORMANCE
static void performanceMeasureTask(PVOID pArg)
{
    PSPIDEVICEEXTENSION pSpiDevExt  = (PSPIDEVICEEXTENSION)pArg;
    DWORD startTime = GetTickCount();
    DWORD testPeriod = 0;
    g_RecievedBytes = 0;

    while (1)
    {
        Sleep(1000);
        DBGMSG(ZONE_ERROR, (TEXT("SmsSpi: Current performance %d KB/Sec.\r\n"),g_RecievedBytes / (GetTickCount() - startTime)));
        testPeriod++;
        if (testPeriod >=30)
        {
            startTime = GetTickCount();
            g_RecievedBytes = 0;
        }


    }
}
#endif

static void smsspi_interruptHandler(PVOID pArg)
{
    PSPIDEVICEEXTENSION pSpiDevExt  = (PSPIDEVICEEXTENSION)pArg;
    DBGMSG(ZONE_INFO, (TEXT("SmsSpi: Interrupt().\r\n")));
    SetEvent(pSpiDevExt->transferMsgQueue);
}


static VOID SpiTransferThread(PVOID pArg)
{
    PSPIDEVICEEXTENSION pSpiDevExt  = (PSPIDEVICEEXTENSION)pArg;
    struct spi_msg *msg;

    while (1)
    {
        WaitForSingleObject(pSpiDevExt->transferMsgQueue, INFINITE); 
        
        msg = (struct spi_msg *)GetEventData(pSpiDevExt->transferMsgQueue);

        if (msg)
        {
            DBGMSG(ZONE_INFO, (TEXT("SmsSpi: Transfering packet, buf=0x%x, len=%d.\r\n"), msg->buf, msg->len));
            //Rock 090507
            smsspi_common_transfer_msg(&pSpiDevExt->dev, msg, pSpiDevExt->PaddingAllowed);
            SetEventData(pSpiDevExt->transferMsgQueue, 0);
            SetEvent(pSpiDevExt->WriteOperation);
        }
        else
        {   //Rock 090507
            smsspi_common_transfer_msg(&pSpiDevExt->dev, NULL, pSpiDevExt->PaddingAllowed);
        }
        
    }

}

static rx_buffer_st* allocate_rx_buf(void* context, int size)
{
    PSPIDEVICEEXTENSION pSpiDevExt = (PSPIDEVICEEXTENSION)context;
    if (size <= RX_BUF_SIZE)
    {
        return &pSpiDevExt->rxbuf;
    }
    else
        return NULL;
}

static void free_rx_buf (void* Context, rx_buffer_st* buf)
{
}

/*************************************************************************************
                        Driver Actual Implementation 

*************************************************************************************/
/*************************************************************************************
FUNCTION NAME:    DllEntry

DESCRIPTION:    Standard DLLEntry point for a DLL

PARAMETERS:        [IN]    HANDLE    hDllHandle    -    Instance to dll module 
                [IN]    DWORD    dwReasone    -    Reasone for the calling the routine 
                [IN]    LPVOID    lpReserved    -    Reserved    
                                           
RETURN VALUE:    None

REMARKS            NONE
*************************************************************************************/
BOOL WINAPI DllEntry(
   HANDLE hDllHandle, 
   DWORD  dwReason, 
   LPVOID lpreserved
   ) 
{
    BOOL bRc = TRUE;
    
    UNREFERENCED_PARAMETER(hDllHandle);
    UNREFERENCED_PARAMETER(lpreserved);
    
    switch (dwReason) {
        case DLL_PROCESS_ATTACH: 
            {
            DEBUGREGISTER((HINSTANCE)hDllHandle);
            DEBUGMSG(1,(_T("*** DLL_PROCESS_ATTACH - Current Process: 0x%x, ID: 0x%x ***\r\n"),
                GetCurrentProcess(), GetCurrentProcessId()));
            } 
            break;
            
        case DLL_PROCESS_DETACH: 
            {
            DEBUGMSG(1,(_T("*** DLL_PROCESS_DETACH - Current Process: 0x%x, ID: 0x%x ***\r\n"),
                GetCurrentProcess(), GetCurrentProcessId()));
            } 
            break;
            
        default:
            break;
    }
    
    return bRc;
}


static VOID FreeAllocatedResources(PSPIDEVICEEXTENSION pSpiDevExt)
{
    DMA_ADAPTER_OBJECT adapter;

    if (pSpiDevExt)
    {
        pSpiDevExt->pBD_ReadCBFunc = NULL;
        Sleep(1); // Make sure the MsgFound finish before removing GenDrv to avoid race condition.
        if (pSpiDevExt->hSmsGenDrv != INVALID_HANDLE_VALUE)
        {
            DeactivateDevice(pSpiDevExt->hSmsGenDrv);
            pSpiDevExt->hSmsGenDrv = INVALID_HANDLE_VALUE;
        }
        if (pSpiDevExt->transferThread)
        {
            TerminateThread(pSpiDevExt->transferThread, 0);
            CloseHandle(pSpiDevExt->transferThread);
        }
        if (pSpiDevExt->performanceThread)
        {
            TerminateThread(pSpiDevExt->performanceThread, 0);
            CloseHandle(pSpiDevExt->performanceThread);
        }
        if (pSpiDevExt->transferMsgQueue)
        {
            CloseHandle(pSpiDevExt->transferMsgQueue);
        }
        if (pSpiDevExt->WriteOperation)
        {
            CloseHandle(pSpiDevExt->WriteOperation);
        }

        if (pSpiDevExt->dev.rxbuf)
        {
            LocalFree(pSpiDevExt->dev.rxbuf);
        }
        if (pSpiDevExt->phyDrv)
        {
            smsspiphy_deinit(pSpiDevExt->phyDrv);
            pSpiDevExt->phyDrv = NULL;
        }
        if (pSpiDevExt->txbuf)
        {
            PHYSICAL_ADDRESS phyAddr;
            phyAddr.QuadPart = pSpiDevExt->txbuf_phy_addr;
            HalFreeCommonBuffer(&adapter, TX_BUF_SIZE, phyAddr, pSpiDevExt->txbuf, FALSE);
        }
        if (pSpiDevExt->rxbuf.ptr)
        {
            PHYSICAL_ADDRESS phyAddr;
            phyAddr.QuadPart = pSpiDevExt->rxbuf.phy_addr;
            HalFreeCommonBuffer(&adapter, TX_BUF_SIZE, phyAddr, pSpiDevExt->rxbuf.ptr, FALSE);
        }
        LocalFree(pSpiDevExt);
        pSpiDevExt = NULL;
    }
}


/*************************************************************************************
FUNCTION NAME:    SPI_Init

DESCRIPTION:    Streame Driver Init entry point

PARAMETERS:        [IN]    Context - pointer to the registry path for the device's parameters.
                                           
RETURN VALUE:    None

REMARKS            NONE
*************************************************************************************/
DWORD WINAPI SPI_Init(PVOID Context)
{
    DMA_ADAPTER_OBJECT adapter;
    //MSGQUEUEOPTIONS    msgOptions;
    PHYSICAL_ADDRESS phyAddr;
    PSPIDEVICEEXTENSION pSpiDevExt = (PSPIDEVICEEXTENSION)LocalAlloc(LPTR,sizeof(SPIDEVICEEXTENSION));
    spi_dev_cb_st cbParams;
    
    DBGMSG(ZONE_INIT, (TEXT("SmsSpi: SPI_Init() Start.\r\n")));
    if(pSpiDevExt == NULL)
    {
        DBGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("SmsSpi: SPI_Init() failed to allocate memory for handle.\r\n")));
        return 0;
    }
    memset (pSpiDevExt, 0, sizeof(SPIDEVICEEXTENSION));
    
    pSpiDevExt->txbuf = HalAllocateCommonBuffer(&adapter, TX_BUF_SIZE, &phyAddr, FALSE);
    if (NULL == pSpiDevExt->txbuf)
    {
        DBGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("SmsSpi: SPI_Init() failed to alloc tx buf.\r\n")));
        FreeAllocatedResources(pSpiDevExt);
        return 0;        
    }
    pSpiDevExt->txbuf_phy_addr = phyAddr.LowPart;
    
    pSpiDevExt->rxbuf.ptr = HalAllocateCommonBuffer(&adapter, RX_BUF_SIZE, &phyAddr, FALSE);
    if (NULL == pSpiDevExt->rxbuf.ptr)
    {
        DBGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("SmsSpi: SPI_Init() failed to alloc rx buf.\r\n")));
        FreeAllocatedResources(pSpiDevExt);
        return 0;        
    }
    pSpiDevExt->rxbuf.phy_addr = phyAddr.LowPart;
    
    pSpiDevExt->PaddingAllowed = 1;
    pSpiDevExt->pBD_ReadCBFunc = NULL;

    pSpiDevExt->phyDrv = smsspiphy_init((void*)Context, smsspi_interruptHandler, pSpiDevExt);
    if (NULL == pSpiDevExt->phyDrv)
    {
        DBGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("SmsSpi: SPI_Init() failed to initialize physical driver.\r\n")));
        FreeAllocatedResources(pSpiDevExt);
        return 0;
    }
    pSpiDevExt->dev.rxbuf = LocalAlloc(LPTR, RX_BUF_SIZE);
    if (NULL == pSpiDevExt->dev.rxbuf)
    {
        DBGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("SmsSpi: SPI_Init() failed to allocate memory for RX buffer.\r\n")));
        FreeAllocatedResources(pSpiDevExt);
        return 0;
    }

    cbParams.transfer_data_cb = smsspibus_xfer;
    cbParams.msg_found_cb = MsgFound;
    cbParams.allocate_rx_buf = allocate_rx_buf;
    cbParams.free_rx_buf = free_rx_buf;
    if(-1 == smsspicommon_init(&pSpiDevExt->dev, pSpiDevExt, pSpiDevExt->phyDrv, &cbParams))
    {
        DBGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("SmsSpi: SPI_Init() failed to smsspicommon_init.\r\n")));
        FreeAllocatedResources(pSpiDevExt);
        return 0;
    }

    memcpy (pSpiDevExt->txbuf, preamble_pattern, sizeof(preamble_pattern));
    
    pSpiDevExt->WriteOperation = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (pSpiDevExt->WriteOperation == NULL)
    {
        DBGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("SmsSpi: SPI_Init() failed to create Write event.\r\n")));
        FreeAllocatedResources(pSpiDevExt);
        return 0;
    }
/*
    msgOptions.dwSize = sizeof(msgOptions);
    msgOptions.dwFlags = 0;
    msgOptions.dwMaxMessages = 5;
    msgOptions.cbMaxMessage = sizeof(struct spi_msg);
    msgOptions.bReadAccess = TRUE;
*/
    pSpiDevExt->transferMsgQueue = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (pSpiDevExt->transferMsgQueue == NULL)
    {
        DBGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("SmsSpi: SPI_Init() failed to create transferMsgQueue.\r\n")));
        FreeAllocatedResources(pSpiDevExt);
        return 0;
    }

    pSpiDevExt->transferThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)SpiTransferThread, pSpiDevExt, 0, NULL);
    if (pSpiDevExt->transferThread == NULL)
    {
        DBGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("SmsSpi: SPI_Init() failed to create transferThread thread.\r\n")));
        FreeAllocatedResources(pSpiDevExt);
        return 0;
    }

    
    //if (CeSetThreadPriority(pSpiDevExt->transferThread, 200) == FALSE)
    if (CeSetThreadPriority(pSpiDevExt->transferThread, 120) == FALSE)
    {
        DBGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("SmsSpi: SPI_Init() failed to set transferThread thread priority.\r\n")));
        FreeAllocatedResources(pSpiDevExt);
        return 0;
    }
#ifdef MEASURE_PERFORMANCE
    pSpiDevExt->performanceThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)performanceMeasureTask, pSpiDevExt, 0, NULL);
#endif
    
    return (DWORD)pSpiDevExt;
}
    
/*************************************************************************************
FUNCTION NAME:    SPI_Deinit

DESCRIPTION:    Streame Driver Deinit entry point

PARAMETERS:        [IN]    Context - N/A
                                           
RETURN VALUE:    None

REMARKS            NONE
EXAMPLES        NONE
*************************************************************************************/
BOOL WINAPI SPI_Deinit(DWORD dwContext)
{
    PSPIDEVICEEXTENSION pSpiDevExt = (PSPIDEVICEEXTENSION)dwContext;

    FreeAllocatedResources(pSpiDevExt);
    return TRUE;
}


/*************************************************************************************
FUNCTION NAME:    SPI_Open

DESCRIPTION:    Streame Driver Open entry point

PARAMETERS:        [IN]    Context   - 
                [IN]    Access      -    N/A.
                [IN]    ShareMode -  N/A.
                                           
RETURN VALUE:    None

REMARKS            NONE
*************************************************************************************/
DWORD WINAPI SPI_Open(
                        DWORD Context, 
                        DWORD Access,
                        DWORD ShareMode)
{

    DBGMSG(ZONE_INFO, (TEXT("SmsSpi: SPI_Open()\r\n")));
    return (DWORD)Context;

}


/*************************************************************************************
FUNCTION NAME:    SPI_Close

DESCRIPTION:    Streame Driver Close entry point

PARAMETERS:        [IN]    Context   - 
                [IN]    Access      -    N/A.
                [IN]    ShareMode -  N/A.
                                           
RETURN VALUE:    None

REMARKS            NONE
*************************************************************************************/
BOOL WINAPI SPI_Close(DWORD Context) 
{
    DBGMSG(ZONE_INFO, (TEXT("SmsSpi: SPI_Close()\r\n")));
    
    return TRUE;
}


/*************************************************************************************
FUNCTION NAME:    SPI_Read

DESCRIPTION:    Streame Driver Read entry point

PARAMETERS:        [IN]    DWORD  dwContext   - 
                [IN]    LPVOID pBuffer - User input buffer.
                [IN]    DWORD  BufferLength
                                           
RETURN VALUE:    None

REMARKS            NONE

*************************************************************************************/
DWORD WINAPI SPI_Read(DWORD  dwContext, LPVOID pBuffer, DWORD  BufferLength) 
{
    DBGMSG(ZONE_ERROR, (TEXT("SmsSpi: SPI_Read() called, but not supported\r\n")));
    return (-1);
}

/*************************************************************************************
FUNCTION NAME:    SPI_Write

DESCRIPTION:    Streame Driver Write entry point

PARAMETERS:        [IN]    DWORD  dwContext  
                [IN]    LPVOID pBuffer - User input buffer.
                [IN]    DWORD  BufferLength
                                           
RETURN VALUE:    None

REMARKS            NONE
*************************************************************************************/
DWORD WINAPI SPI_Write(DWORD  dwContext, LPVOID pBuff, DWORD  BufferLength) 
{    
    int     Cnt;
    int     AddingPreamble, WrittenBytes;
    static struct spi_msg   txmsg;
    PSPIDEVICEEXTENSION pSpiDevExt  = (PSPIDEVICEEXTENSION)dwContext;
    
    DBGMSG(ZONE_INFO, (TEXT("SmsSpi: SPI_Write() Writing %d bytes.\r\n"), BufferLength));

    AddingPreamble = 1;
    if (BufferLength > 0x1000)
    { /* The FW is the only long message. Do not add preamble, and do not padd it*/
        pSpiDevExt->PaddingAllowed = 0;
        AddingPreamble = 0;
        BufferLength += 4;
        smschipreset(pSpiDevExt->phyDrv);        
    }
    WrittenBytes = 0;
        
    while (BufferLength > 0)
    {
        ResetEvent(pSpiDevExt->WriteOperation);    
        txmsg.buf = pSpiDevExt->txbuf;
        txmsg.buf_phy_addr = pSpiDevExt->txbuf_phy_addr;
        if (AddingPreamble == 1)
        {
            DBGMSG(ZONE_INFO, (TEXT("SmsSpi: SPI_Write() Adding peamble.\r\n")));
            Cnt = min((int)(BufferLength + sizeof(preamble_pattern)), (int)TX_BUF_SIZE);
            //RETAILMSG(1,  (TEXT("SmsSpi: SPI_Write() Adding peamble len=%d.\r\n"), Cnt));
            txmsg.len = Cnt;
            memcpy (pSpiDevExt->txbuf, preamble_pattern, sizeof(preamble_pattern));
            memcpy(pSpiDevExt->txbuf+sizeof(preamble_pattern), pBuff, Cnt - sizeof(preamble_pattern));
            WrittenBytes += (Cnt - sizeof(preamble_pattern));
            BufferLength -= (Cnt - sizeof(preamble_pattern));        
        }
        else
        {
            DBGMSG(ZONE_INFO, (TEXT("SmsSpi: SPI_Write() No preamble added.\r\n")));
            Cnt = min(BufferLength, TX_BUF_SIZE);
            //RETAILMSG(1,  (TEXT("SmsSpi: SPI_Write() No preamble added. len=%d\r\n"), Cnt));
            txmsg.len = Cnt;
            memcpy(pSpiDevExt->txbuf, (CHAR*)pBuff, Cnt);
            WrittenBytes += Cnt;
            BufferLength -= Cnt;        
        }
        memset (pSpiDevExt->txbuf + Cnt, 0, TX_BUF_SIZE - Cnt);
        DBGMSG(ZONE_INFO, (TEXT("SmsSpi: SPI_Write() Sending to transfer queue. buf = 0x%x, len=%d.\r\n"), txmsg.buf, txmsg.len));
        SetEventData(pSpiDevExt->transferMsgQueue, (DWORD)&txmsg);
        SetEvent(pSpiDevExt->transferMsgQueue);
        WaitForSingleObject(pSpiDevExt->WriteOperation, INFINITE);
        memset (pSpiDevExt->txbuf, 0, Cnt);
        (PCHAR)pBuff+=Cnt;    /*lint !e63*/    
        AddingPreamble = 0;
    }
    pSpiDevExt->PaddingAllowed = 1;
    DBGMSG(ZONE_INFO, (TEXT("SmsSpi: SPI_Write() Write exits.\r\n")));
    return WrittenBytes;
    
}

/*************************************************************************************
FUNCTION NAME:    SPI_IOControl

DESCRIPTION:    Streame Driver IOControl entry point

PARAMETERS:        [IN]    DWORD  dwContext - 
                [IN]    DWORD  Ioctl - Command
                [IN]    PUCHAR pInBuf - Input Buffer
                [IN]    DWORD  InBufLen - Input Buffer Length 
                [IN]    PUCHAR pOutBuf - Output Buffer
                [IN]    DWORD  OutBufLen - Output Buffer Length
                [IN]    PDWORD pdwBytesTransferred - Bytes Transfferd.
                                           
RETURN VALUE:    None

REMARKS            NONE
*************************************************************************************/
BOOL WINAPI SPI_IOControl(
    DWORD  dwContext,
    DWORD  Ioctl,
    PUCHAR pInBuf,
    DWORD  InBufLen, 
    PUCHAR pOutBuf,
    DWORD  OutBufLen,
    PDWORD pdwBytesTransferred
   )
{    
    BOOL retVal;
    PSPIDEVICEEXTENSION pSpiDevExt  = (PSPIDEVICEEXTENSION)dwContext;

    retVal = FALSE;

    switch(Ioctl)
    {
        case SIANO_BD_IOCTL_REGISTER_READ_CB:/*lint !e650*/
            if ((pInBuf != NULL) && (InBufLen >= sizeof(BD_IOCTL_REGISTER_READ_PARAMS_ST)))
            {
                pSpiDevExt->hBDContext = ((PBD_IOCTL_REGISTER_READ_PARAMS_ST)pInBuf)->hContext;
                pSpiDevExt->pBD_ReadCBFunc = ((PBD_IOCTL_REGISTER_READ_PARAMS_ST)pInBuf)->pBD_ReadCBFunc;
                retVal = TRUE;
            }
            break;

        case SIANO_BD_IOCTL_WRITE_FW_BUFF_TO_DEVICE:/*lint !e650*/
            if ((pInBuf != NULL) && (InBufLen >= sizeof(BD_IOCTL_DOWNLOAD_FW_ST)))/*lint !e40*/
            {
                WriteFWtoStellar(pSpiDevExt->phyDrv,((PBD_IOCTL_DOWNLOAD_FW_ST)pInBuf)->buf,((PBD_IOCTL_DOWNLOAD_FW_ST)pInBuf)->size);/*lint !e10*//*lint !e40*/
                retVal = TRUE;
            }
            break;
            
        case SIANO_BD_IOCTL_PREPARE_FOR_FW_DNL: /*lint !e30*//*lint !e40*/
            prepareForFWDnl(pSpiDevExt->phyDrv);
            retVal = TRUE;
            break;
            
        case SIANO_BD_IOCTL_FW_DNL_COMPLETE: /*lint !e30*//*lint !e40*/
            fwDnlComplete(pSpiDevExt->phyDrv);
            retVal = TRUE;
            break;

        case MTV_POWER_ON:/*lint !e30*//*lint !e40*/
            if (!PowerOn(pSpiDevExt->phyDrv))
            {
                /*DBGMSG(ZONE_ERROR, (TEXT("SmsSpi: siano power on error!\r\n")));*/
                NKDbgPrintfW(TEXT("%s:%u:SmsSpi: siano power on error!\r\n"),
                    TEXT(__FUNCTION__), __LINE__);
            }
            else
            {
                retVal = TRUE;
            }
            break;

        case MTV_POWER_OFF:/*lint !e30*//*lint !e40*/
            PowerOff(pSpiDevExt->phyDrv);
            retVal = TRUE;
            break;
            
        default:
            break;
    }

    return retVal;

}


/*************************************************************************************
FUNCTION NAME:    SPI_Seek

DESCRIPTION:    Streame Driver Seek entry point

PARAMETERS:        [IN]    DWORD  dwContext   - 
                [IN]    LONG Position.
                [IN]    DWORD  Type
                                           
RETURN VALUE:    None

REMARKS            Not implemented for this device
*************************************************************************************/
ULONG SPI_Seek(
   PVOID Context,
   LONG  Position,
   DWORD Type
   )
{
    UNREFERENCED_PARAMETER(Context);
    UNREFERENCED_PARAMETER(Position);
    UNREFERENCED_PARAMETER(Type);
    
    return (ULONG)-1;
}


/*************************************************************************************
FUNCTION NAME:    SPI_PowerDown

DESCRIPTION:    PowerDown entry point

PARAMETERS:        [IN]    DWORD  dwContext   - pointer to a USBGEN_CONTEXT sructure.
                
                                           
RETURN VALUE:    None

REMARKS            Not implemented for this device
*************************************************************************************/
VOID WINAPI SPI_PowerDown(DWORD dwContext)
{
    UNREFERENCED_PARAMETER(dwContext);
}


/*************************************************************************************
FUNCTION NAME:    SPI_PowerUp

DESCRIPTION:    PowerUp entry point

PARAMETERS:        [IN]    DWORD  dwContext   - pointer to a USBGEN_CONTEXT sructure.
                
                                           
RETURN VALUE:    None

REMARKS            Not implemented for this device
*************************************************************************************/
VOID WINAPI SPI_PowerUp(DWORD dwContext)
{
    UNREFERENCED_PARAMETER(dwContext);    
}

